import json
import random
from tkinter import *
from tkinter import ttk
import tkinter.font as tkFont
from collections import deque


DBFile = '小学一至六年级生字表.json'

P0 = 0.3
P1 = 0.8
P2 = 0.95
P3 = 1.0

histroy = deque(maxlen=8)

jsonDB = {}


def loadDB():
    global jsonDB
    with open(DBFile, 'r', encoding='utf-8') as fp:
        jsonDB = json.load(fp)


def updateDB():
    with open(DBFile, 'w', encoding='utf-8') as fp:
        json.dump(jsonDB, fp, sort_keys=False, ensure_ascii=False)


def get_next():
    level = combo_level_var.get()
    v, c = getItem(level)
    label_item_var.set(c)
    
    if v == '0':
        label_current_var.set('不认识')
    elif v == '1':
        label_current_var.set('不确定')
    elif v == '2':
        label_current_var.set('认识')
    elif v == '3':
        label_current_var.set('熟悉')

    c0 = len(jsonDB[level]['0'])
    c1 = len(jsonDB[level]['1'])
    c2 = len(jsonDB[level]['2'])
    c3 = len(jsonDB[level]['3'])
    ss = '不认识的 {0}, 不确定的 {1}, 认识的 {2}, 熟悉的 {3}'.format(c0, c1, c2, c3)
    label_count_var.set(ss)


def combo_level_selected(event):
    get_next()

def __getItem(level):
    r = random.random()
    v = ''
    if r < P0:
        v = '0'
    elif r < P1:
        v = '1'
    elif r < P2:
        v = '2'
    elif r < P3:
        v = '3'
    
    d = jsonDB[level][v]
    if len(d) > 0:
        c = random.choice(list(d.keys()))
        return (v, c)
    else:
        return (v, '')


def getItem(level):
    v= ''
    c = ''
    for i in range(1000):
        v, c = __getItem(level)
        if (len(c) > 0) and (c not in histroy):
            histroy.append(c)
            break
    return v, c


def __removeItem(level, c):
    for d in jsonDB[level].keys():
        if c in jsonDB[level][d]:
            del jsonDB[level][d][c]


def markItem(flag):
    level = combo_level_var.get()
    c = label_item_var.get()
    v = label_current_var.get()

    if v == '熟悉' and flag == '2':
        flag = '3'

    d = jsonDB[level][flag]
    if c in d:
        d[c] += 1
    else:
        __removeItem(level, c)
        d[c] = 1
    
    if flag == '2':
        if d[c] > 5:
            __removeItem(level, c)
            jsonDB[level]['3'][c] = 1
    
    updateDB()
    get_next()


def markItem0():
    markItem('0')


def markItem1():
    markItem('1')


def markItem2():
    markItem('2')


loadDB()


root = Tk()
root.title('小学一至六年级生字学习')

combo_level_var = StringVar()
combo_level = ttk.Combobox(root, textvariable=combo_level_var, width=22)
combo_level['values'] = tuple(jsonDB.keys())
combo_level.current(0)
combo_level.bind('<<ComboboxSelected>>', combo_level_selected)

label_item_var = StringVar()
ft1 = tkFont.Font(family='等线', size=180)
label_item = Label(root, font=ft1, textvariable=label_item_var, relief=GROOVE)
                   
label_current_var = StringVar()
label_current = Label(root, textvariable=label_current_var)

bt_mark0 = Button(root, text='不认识', width=25, height=5,
                  bg='#FAEBD7', command=markItem0)
bt_mark1 = Button(root, text='不确定', width=25, height=5,
                  bg='#FFA500', command=markItem1)
bt_mark2 = Button(root, text='认识', width=25, height=5,
                  bg='#98FB98', command=markItem2)
label_count_var = StringVar()
label_count = Label(root, textvariable=label_count_var)

combo_level.grid(row=0, column=0, padx=30, pady=10)
label_item.grid(row=0, column=1, padx=80, pady=80)
label_current.grid(row=0, column=2, padx=30, pady=10)
bt_mark0.grid(row=1, column=0, padx=30, pady=10)
bt_mark1.grid(row=1, column=1, padx=30, pady=10)
bt_mark2.grid(row=1, column=2, padx=30, pady=10)
label_count.grid(row=2, column=1, padx=10, pady=10)

get_next()

root.mainloop()
